package com.seven.first.suite.annotation.handler;

import com.google.common.collect.Lists;
import com.seven.first.suite.annotation.po.SevenDeleteField;
import com.seven.first.suite.util.SevenStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.persistence.Column;
import javax.persistence.Table;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

/**
 * @ClassName TableAnnotationHandler
 * @Description 通过注解获取指定值
 * @Author seven
 * @Date 2022/5/1616:04
 * @Version 1.0
 **/
public class TableAnnotationHandler {



    /**
     * 获取实体类上sevenDeleteField注解中的值
     * @param classz
     * @return
     */
    public static DeleteField getDeleteFieldValue(Class<?> classz){
        Assert.isNull(classz,"classz is be null !!!");

        SevenDeleteField annotation = classz.getAnnotation(SevenDeleteField.class);

        Assert.isNull(annotation,"There is no such annotation (SevenDeleteField) on this class !!!");

        String value = annotation.value();
        int deleteValue = annotation.deleteValue().getIndex();
        int existValue = annotation.existValue().getIndex();


        //如果该注解值为空,则获取该注解所在字段的名称
        if(StringUtils.isEmpty(value)){
            List<String> feildsName = getFeildsName(classz, SevenDeleteField.class, true);
            return new DeleteField(feildsName.get(0));
        }
        return new DeleteField(value,deleteValue,existValue);

    }

    /**
     * 获取某一个实体类中标有javax.persistence.Column注解的值
     * @param classz
     * @return
     */
    public static List<String> getFieldsCloumnName(Class<?> classz){
        Assert.isNull(classz,"classz is be null !!!");

        Field[] fields = classz.getFields();
        List<String> temps = Lists.newArrayList();
        for (Field field : fields) {
            Column annotation = field.getAnnotation(Column.class);
            if(annotation != null){
                String name = annotation.name();
                //如果该注解的name值为空，则取字段名称，驼峰命名改为下滑线
                if(StringUtils.isEmpty(name)){
                    name = SevenStringUtils.upperCharToUnderLine(field.getName());
                }
                temps.add(name);
            }
        }
        return temps;
    }

    /**
     * 获取字段中有这个注解的字段的名称
     * @param classz
     * @return
     */
    private static List<String> getFeildsName(Class<?> classz, Class<? extends Annotation> annotationClass,boolean onlyOneFlag) {
        Field[] fields = classz.getFields();
        if(fields.length == 0){
            throw  new RuntimeException("There is no field on this class ("+ classz.getName()+") !!!");
        }

        List<String> tempList = Lists.newArrayList();
        for (Field field : fields) {
            Annotation annotation = field.getAnnotation(annotationClass);
            if(annotation != null){
                tempList.add(field.getName());
            }
        }

        if(CollectionUtils.isEmpty(tempList)){
            throw  new RuntimeException("There is no field("+annotationClass.getName()+") on this class ("+ classz.getName()+") !!!");
        }
        if(onlyOneFlag && tempList.size() != 1){
            throw  new RuntimeException("There can only be one field("+annotationClass.getName()+") of this annotation under this class !!!");
        }

        List<String> result = Lists.newArrayList();
        for (String name : tempList) {
            String finalName = SevenStringUtils.upperCharToUnderLine(name);
            result.add(finalName);
        }
        return result;
    }

    /**
     * 获取实体类上javax.persistence.Table注解中name的值
     * @param classz
     * @return
     */
    public static String getTableNameValue(Class<?> classz){
        Assert.isNull(classz,"classz is be null !!!");

        Table annotation = classz.getAnnotation(Table.class);

        Assert.isNull(annotation,"There is no such annotation (javax.persistence.Table) on this class（"+classz.getName()+"） !!!");

        String value = annotation.name();

        if(StringUtils.isEmpty(value)){
            String name = classz.getName();
            return SevenStringUtils.upperCharToUnderLine(name);
        }
        return value;
    }

}
